package com.browsesoft.htmlcomponent;

import java.util.Calendar;
import java.util.Date;
import java.util.GregorianCalendar;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.w3c.dom.Text;

import com.browsesoft.ExtendElement;

public class HTMLCalendarComponent extends HTMLBasicComponent {
	/**
	 * 定义一个日历
	 */
	private Calendar gc = new GregorianCalendar();

	// 行格元素
	private Element tr;

	// 科隆TD
	private Element haveAppointTD;

	private Element noAppointTD;

	public HTMLCalendarComponent(HTMLBasicComponent parent) throws Exception {
		super(parent);
	}

	/**
	 * 初始化时创建子组件并保存模板中该组件的description元素
	 * 
	 * @param request
	 * @param e
	 * @throws Exception
	 */
	public void init(HttpServletRequest request, Element e) throws Exception {
		// 创建子组件并保存组件元素
		super.init(request, e);
		// 初始化日历
		gc.setTime(new Date());
		// 行格元素
		tr = (Element) ((Node) ExtendElement.findElements(this.element, "id",
				"tr").get(0)).cloneNode(false);
		// 科隆TD
		haveAppointTD = (Element) ((Node) ExtendElement.findElements(
				this.element, "id", "have_appoint").get(0)).cloneNode(true);
		noAppointTD = (Element) ((Node) ExtendElement.findElements(
				this.element, "id", "no_appoint").get(0)).cloneNode(true);
	}

	/**
	 * 
	 * 
	 */
	protected void updateElement() throws Exception {
		// 表元素
		Element table = (Element) ExtendElement.findElements(this.element,
				"id", "table").get(0);
		// 清空表格内容
		ExtendElement.removeNodes((Element) table.getParentNode(), "table");
		// 月元素
		Element month = (Element) ExtendElement.findElements(this.element,
				"id", "month").get(0);
		// 清空月内容
		ExtendElement.removeNodes((Element) month.getParentNode(), "select");
		// 年元素
		Element year = (Element) ExtendElement.findElements(this.element, "id",
				"year").get(0);
		// 清空年内容
		ExtendElement.removeNodes((Element) year.getParentNode(), "select");
		// 根据gc显示
		showDate(table, gc);
		showMonth(month, gc);
		showYear(year, gc);
	}

	/**
	 * 根据gc显示日期
	 * 
	 * @param gc
	 */
	private void showDate(Element table, Calendar calendar) {
		// 从月的第一天开始计算今天是星期几
		Calendar firstDay = new GregorianCalendar(calendar
				.get(GregorianCalendar.YEAR), calendar
				.get(GregorianCalendar.MONTH), 1);
		// 将日期填入周内
		int start = firstDay.get(GregorianCalendar.DAY_OF_WEEK);
		Object data[] = new Object[42];
		for (int i = 0; i < 42; i++) {
			data[i] = "*";
		}
		for (int i = start - 1, j = 1; j <= firstDay
				.getMaximum(GregorianCalendar.DAY_OF_MONTH); j++, i++) {
			data[i] = new GregorianCalendar(calendar
					.get(GregorianCalendar.YEAR), calendar
					.get(GregorianCalendar.MONTH), j);
		}
		// 给表格添加内容
		for (int i = 0; i < 6; i++) {
			Element row = (Element) tr.cloneNode(false);
			for (int j = 0; j < 7; j++) {
				Element cell = null;
				Text text = null;
				// 实现的model
				HTMLCalendarModel calModel = (HTMLCalendarModel) this.model;
				// 如果不是日历，则写入"*"
				if (data[i * 7 + j] instanceof String) {
					cell = (Element) noAppointTD.cloneNode(false);
				} else if (data[i * 7 + j] instanceof GregorianCalendar) {
					// 如果预约了
					if (calModel.isAppoint((GregorianCalendar) data[7 * i + j])) {
						cell = (Element) haveAppointTD.cloneNode(true);
					} else {
						cell = (Element) noAppointTD.cloneNode(true);
					}
					int temp = ((GregorianCalendar) data[i * 7 + j])
							.get(GregorianCalendar.DAY_OF_MONTH);
					int tempmonth = ((GregorianCalendar) data[i * 7 + j])
							.get(GregorianCalendar.MONTH);
					Element link = (Element) ExtendElement.findElements(cell,
							"type", "link").get(0);
					text = ((HTMLPage) getPage()).getDocument().createTextNode(
							Integer.toString(temp));
					ExtendElement.replaceElementContext(link, text);
					// 更改onclick
					String onclick = link.getAttribute("onclick");
					// 定义天
					String day = new String();
					String month = new String();
					if (Integer.toString(tempmonth).length() == 1) {
						month = "0" + Integer.toString(tempmonth);
					} else {
						month = Integer.toString(tempmonth);
					}
					if (Integer.toString(temp).length() == 1) {
						day = "0" + Integer.toString(temp);
					} else {
						day = Integer.toString(temp);
					}
					// 取日期
					onclick = onclick.replaceAll("point=", "point="
							+ ((GregorianCalendar) data[i * 7 + j])
									.get(GregorianCalendar.YEAR) + month + day);
					// 设置onclick
					link.setAttribute("onclick", onclick);
				}
				// 加入行
				row.appendChild(cell);
			}
			// 加入表
			table.appendChild(row);
		}
	}

	/**
	 * 根据gc显示日期
	 * 
	 * @param gc
	 */
	private void showYear(Element year, Calendar calendar) {
		//
		for (int i = 2000; i < 2020; i++) {
			// 构造选择项
			Element option = this.getPage().getDocument().createElement(
					"option");
			year.appendChild(option);
			// 设置选择项内容
			Text text = getPage().getDocument().createTextNode(
					Integer.toString(i));
			option.appendChild(text);
		}
		// 设置选中的值
		String selectedYear = Integer.toString(gc.get(GregorianCalendar.YEAR));
		NodeList nodelist = year.getChildNodes();
		for (int i = 0; i < nodelist.getLength(); i++) {
			// 是OPTION元素
			if (nodelist.item(i).getNodeType() == Node.ELEMENT_NODE) {
				Element element = (Element) nodelist.item(i);
				Text text = (Text) ExtendElement.findElementContext(element)
						.get(0);
				String context = (String) text.getData();
				if (context.equals(selectedYear)) {
					element.setAttribute("selected", "selected");
				}
			}
		}
	}

	/**
	 * 根据gc显示日期
	 * 
	 * @param gc
	 */
	private void showMonth(Element month, Calendar calendar) {
		// 添加月
		for (int i = 1; i < 13; i++) {
			// 构造选择项
			Element option = this.getPage().getDocument().createElement(
					"option");
			month.appendChild(option);
			// 设置选择项内容
			Text text = getPage().getDocument().createTextNode(
					Integer.toString(i));
			option.appendChild(text);
		}
		// 设置选中的值
		int temp = gc.get(GregorianCalendar.MONTH);
		temp = temp + 1;
		String selectedMonth = Integer.toString(temp == 13 ? 1 : temp);
		NodeList nodelist = month.getChildNodes();
		for (int i = 0; i < nodelist.getLength(); i++) {
			// 是OPTION元素
			if (nodelist.item(i).getNodeType() == Node.ELEMENT_NODE) {
				Element element = (Element) nodelist.item(i);
				Text text = (Text) ExtendElement.findElementContext(element)
						.get(0);
				String context = (String) text.getData();
				if (context.equals(selectedMonth)) {
					element.setAttribute("selected", "selected");
				}
			}
		}
	}

	/**
	 * 处理用户请求，将需要Model处理的内容提交给Model
	 * 
	 * @param request
	 *            客户端请求
	 */
	public void service(HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		super.service(request, response);
		String commit = (String) request.getParameter("commitCalender");
		if (commit != null) {
			if (commit.equals("priview")) {
				gc = new GregorianCalendar(gc.get(GregorianCalendar.YEAR), gc
						.get(GregorianCalendar.MONTH) - 1, gc
						.get(GregorianCalendar.DAY_OF_MONTH));
			}
			if (commit.equals("next")) {
				gc = new GregorianCalendar(gc.get(GregorianCalendar.YEAR), gc
						.get(GregorianCalendar.MONTH) + 1, gc
						.get(GregorianCalendar.DAY_OF_MONTH));
			}
			if (commit.equals("year")) {
				String year = (String) request.getParameter("year");
				gc = new GregorianCalendar(Integer.parseInt(year), gc
						.get(GregorianCalendar.MONTH), gc
						.get(GregorianCalendar.DAY_OF_MONTH));
			}
			if (commit.equals("month")) {
				String month = (String) request.getParameter("month");
				gc = new GregorianCalendar(gc.get(GregorianCalendar.YEAR),
						Integer.parseInt(month) - 1, gc
								.get(GregorianCalendar.DAY_OF_MONTH));
			}
		}
	}
}